package com.jdbc.studyReflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestgetConstructor {
    public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Dog d = new Dog("wuhu");
        Animal a = new Animal();
        Class<?> dogclass = d.getClass();
        Class<?> animalclass = a.getClass();
        //获取所有的构造函数（继承、public）
        Constructor<?>[] constructors1 = animalclass.getConstructors();
        for(Constructor constructor:constructors1){
            System.out.println(constructor);
        }
        System.out.println("+++++++++++++++++++++++");
        //获取指定的构造函数（继承、public）getConstructor需要进行异常处理
        try {
            Constructor constructor1 = dogclass.getConstructor(String.class);
            //Constructor constructor2 = dogclass.getConstructor(int.class);//报错 无法获取private修饰的构造函数
            System.out.println(constructor1);
            //System.out.println(constructor2);//获取不到构造函数，无法输出
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        System.out.println("_________________________");
        //获取所有的构造函数（public protected default private）
        Constructor<?>[] constructors2 = animalclass.getDeclaredConstructors();
        for(Constructor constructor:constructors2){
            System.out.println(constructor);
        }
        System.out.println("------------------------");
        //获取指定的构造函数（public protected default private）getDeclaredConstructor需要进行异常处理
        Constructor constructor3 = animalclass.getDeclaredConstructor(int.class);
        System.out.println(constructor3);

        System.out.println("*************************");
        //获取所有属性(继承、public)
        Field[] animalFields1 = animalclass.getFields();
        //获取所有属性(public、protected、default、private)
        Field[] animalFields2 = animalclass.getDeclaredFields();
        //获取指定属性（继承、public）
        Field animalField1 = dogclass.getField("name");
        //获取指定属性(public、protected、default、private)
        Field animalField2 = animalclass.getDeclaredField("height");
        System.out.println("————————————————————————————");
        for(Field field:animalFields1){
            System.out.println(field);
        }
        System.out.println("————————————————————————————");
        for(Field field:animalFields2){
            System.out.println(field);
        }
        System.out.println("————————————————————————————");
        System.out.println(animalField1);
        System.out.println("————————————————————————————");
        System.out.println(animalField2);


        //获取所有方法(继承、public)
        Method[] methods1 = animalclass.getMethods();
        //获取所有方法(public、protected、default、private)
        Method[] methods2 = animalclass.getDeclaredMethods();
        //获取指定方法(继承、public)
        Method method1 = animalclass.getMethod("setName", String.class);
        //获取指定方法(public、protected、default、private)
        Method method2 = animalclass.getDeclaredMethod("getSex");
        System.out.println("______________________");
        for (Method method:methods1){
            System.out.println(method);
        }
        System.out.println("______________________");
        for (Method method:methods2){
            System.out.println(method);
        }
        System.out.println("______________________");
        System.out.println(method1);
        System.out.println("______________________");
        System.out.println(method2);

        System.out.println("=====================");
        //getSuperclass() 返回父类
        Class superClass = dogclass.getSuperclass();
        System.out.println(superClass);
        System.out.println("=====================");
        //getName() 返回完整类名
        String completeName = dogclass.getName();
        System.out.println(completeName);
        System.out.println("=====================");
        //newInstance() 快速创建一个类的实例 newInstance()只能调用无参构造器 得到一个Object类型的对象
        Object newAnimal = animalclass.newInstance();
        System.out.println(newAnimal);
        //cls.getDeclaredConstructor(Class类型的参数类型).newInstance(参数值) 得到一个Object类型的对象
        Object newDog = dogclass.getDeclaredConstructor(String.class).newInstance("qifei");
        //Object newDog1 = dogclass.newInstance(); Dog类的构造器定义了有参构造器 newInstance()只能调用无参构造器 所以运行时报错
        System.out.println(newDog);

    }
}
class Animal{
    public String name;
    int age;
    protected double weight;
    private double height;
    boolean sex;
    public Animal(){
        System.out.println("Animal的无参构造器");
    }
    public Animal(String name){
        this.name = name;
        System.out.println(this.name);
    }
    public Animal(String name,int age,double weight,double height){
        this.name = name;
        this.age = age;
        this.weight = weight;
        this.height = height;
    }
    private Animal(int age){
        this.age = age;
    }
    protected Animal(double weight){
        this.weight = weight;
    }
    Animal(Boolean sex){
        this.sex = sex;
    }

    public void setName(String name){
        this.name = name;
    }
    protected int getAge(){
        return this.age;
    }
    void setHeight(double height){
        this.height = height;
    }
    private Boolean getSex(){
        return this.sex;
    }
}
class Dog extends Animal{
    public Dog(String name){
        super(name);
        System.out.println("Dog 的构造器");
    }
}
